package com.yy.finvideoplayer.floatwindow

import android.animation.ValueAnimator
import android.annotation.TargetApi
import android.app.AppOpsManager
import android.content.Context
import android.os.Binder
import android.os.Build
import android.provider.Settings
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.FrameLayout
import com.yy.finvideoplayer.Util

/**
 * 视频进出浮窗辅助类
 * @Description: FloatWindowHelp
 * @Author: yiw89
 * @CreateDate: 2025/9/1 14:16
 * @Version: 1.0
 */
class FloatWindowHelp(private val context: Context) :
    FloatMoveView.MoveListener {
    private var windowManage: WindowManage? = null
    private val decorView: ViewGroup
    private var floatMoveView: FloatMoveView? = null
    private lateinit var floatParams: FloatParams
    private var newFloatParams: FloatParams? = null
    private var type = 0

    init {
        type = if (Build.VERSION.SDK_INT >= 26) //8.0新特性
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        else WindowManager.LayoutParams.TYPE_PHONE

        decorView = Util.scanForActivity(context).getWindow().getDecorView() as ViewGroup
    }

    fun enterWindowFloat(
        view: View?,
        floatParams: FloatParams
    ): Boolean {
        if (floatParams.systemFloat && !checkPermission()) {
            return false
        }
        this.floatParams = floatParams
        newFloatParams = floatParams.clone()
        //拦截触摸容器view
        floatMoveView = FloatMoveView(context)
        floatMoveView!!.setMoveListener(this)
        floatMoveView!!.setRount(floatParams.round)
        if (Build.VERSION.SDK_INT >= 11) floatMoveView!!.setAlpha(floatParams.fade)
        floatMoveView!!.addView(view, FrameLayout.LayoutParams(-1, -1))
        //添加进浮窗
        if (floatParams.systemFloat) getWindowManage().addWindowView(
            floatMoveView!!,
            getWindowManage().creatParams(type, floatParams)
        )
        else {
            val l: FrameLayout.LayoutParams = FrameLayout.LayoutParams(floatParams.w, floatParams.h)
            l.leftMargin = (decorView.measuredWidth - floatParams.w) / 2 + floatParams.x
            l.topMargin = (decorView.measuredHeight - floatParams.h) / 2 + floatParams.y
            decorView.addView(floatMoveView, l)
        }

        return true
    }

    fun quitWindowFloat() {
        if (floatMoveView != null) {
            if (floatParams.systemFloat) getWindowManage().removeWindowView(floatMoveView!!)
            else {
                val vp = floatMoveView!!.getParent() as ViewGroup
                vp?.removeView(floatMoveView)
            }
            floatMoveView!!.removeAllViews()
            floatMoveView = null

            newFloatParams = null
            windowManage = null
        }
    }

    override fun move(x: Int, y: Int) {
        if (floatMoveView != null && floatParams.canMove) {
            newFloatParams?.x = floatParams.x + x
            newFloatParams?.y = floatParams.y + y

            val w = decorView.measuredWidth
            val h = decorView.measuredHeight

            if (floatParams.systemFloat) //系统浮窗不能超出边界
                getWindowManage().updateWindowView(
                    floatMoveView!!,
                    getWindowManage().creatParams(type, newFloatParams!!)
                )
            else {
                val l = floatMoveView!!.getLayoutParams() as ViewGroup.MarginLayoutParams
                l.leftMargin = (w - floatParams.w) / 2 + newFloatParams!!.x
                l.topMargin = (h - floatParams.h) / 2 + newFloatParams!!.y
                floatMoveView!!.setLayoutParams(l)
            }
        }
    }

    override fun end() {
        if (floatMoveView == null) return
        floatParams = newFloatParams!!.clone()
        //界面内浮窗超出边界回弹动画
        if (!floatParams.systemFloat and !floatParams.canCross) {
            val w = decorView.measuredWidth
            val h = decorView.measuredHeight
            val maxLeft: Int = w - floatParams.w
            val maxTop: Int = h - floatParams.h
            var newLeft = -1
            var newTop = -1
            //判断是否超出边界,以及超出边界后回弹新位置的坐标
            val l = floatMoveView!!.getLayoutParams() as ViewGroup.MarginLayoutParams
            if (l.leftMargin < 0) newLeft = 0
            if (l.leftMargin > maxLeft) newLeft = maxLeft
            if (l.topMargin < 0) newTop = 0
            if (l.topMargin > maxTop) newTop = maxTop
            if ((newLeft == -1) and (newTop == -1)) return
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) return
            //执行属性动画
            val animator = ValueAnimator.ofFloat(0f, 1.0f)
            animator.setTarget(floatMoveView)
            animator.setDuration(300).start()
            // animator.setInterpolator(value)
            val finalNewLeft = newLeft
            val finalNewTop = newTop
            val finalLeft = l.leftMargin
            val finalTop = l.topMargin
            animator.addUpdateListener { animation ->
                val f = animation.animatedValue as Float
                if (finalNewLeft >= 0) l.leftMargin =
                    (finalLeft + f * (finalNewLeft - finalLeft)).toInt()
                if (finalNewTop >= 0) l.topMargin =
                    (finalTop + f * (finalNewTop - finalTop)).toInt()
                floatMoveView!!.setLayoutParams(l)
                //更新浮窗中心点坐标
                floatParams.x = l.leftMargin + floatParams.w / 2 - w / 2
                floatParams.y = l.topMargin + floatParams.h / 2 - h / 2
            }
        }
    }

    fun getFloatParams(): FloatParams {
        return floatParams
    }


    private fun getWindowManage(): WindowManage {
        if (windowManage == null) windowManage = WindowManage(context)
        return windowManage as WindowManage
    }


    //检查浮窗权限
    fun checkPermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Settings.canDrawOverlays(context)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //AppOpsManager添加于API 19
            checkOps()
        } else {
            //4.4以下一般都可以直接添加悬浮窗
            true
        }
    }


    @TargetApi(Build.VERSION_CODES.KITKAT)
    private fun checkOps(): Boolean {
        try {
            val `object` =
                context.getSystemService(Context.APP_OPS_SERVICE) ?: return false
            val localClass: Class<*> = `object`.javaClass
            val arrayOfClass: Array<Class<*>?> = arrayOfNulls(3)
            arrayOfClass[0] = Integer.TYPE
            arrayOfClass[1] = Integer.TYPE
            arrayOfClass[2] = String::class.java
            val method = localClass.getMethod("checkOp", *arrayOfClass) ?: return false
            val arrayOfObject1 = arrayOfNulls<Any>(3)
            arrayOfObject1[0] = 24
            arrayOfObject1[1] = Binder.getCallingUid()
            arrayOfObject1[2] = context.packageName
            val m = method.invoke(`object`, *arrayOfObject1) as Int
            //4.4至6.0之间的非国产手机，例如samsung，sony一般都可以直接添加悬浮窗
            val b = m == AppOpsManager.MODE_ALLOWED //|| !RomUtils.isDomesticSpecialRom();
            if (!b) type = WindowManager.LayoutParams.TYPE_TOAST
        } catch (ignore: Exception) {
        }
        return true
    }
}